<!doctype html>
<html>
<head>
  <meta charset="utf-8"/>
  <meta http-equiv="X-UA-Compatible" content="IE=7; IE=EmulateIE9; IE=10" />
  <meta name="keywords" content="addMarkerToMap" />
  <title>HERE  Maps API Example: Showing Directions Based on a  URL</title>
  <!-- Set up  constants such as APP ID and token -->
  <script  type="text/javascript" src="../libs/hereAppIdAndToken.js"></script>
  <!-- Bootstrap jQuery Library -->
  <script  type="text/javascript" src="../libs/jQl.min.js"></script>
  <!-- Asynchronously  the  HERE Maps API for JavaScript -->
  <script  type="text/javascript" src="../libs/hereAsyncLoader.js"
    id="HereMapsLoaderScript" /*This identifies  the  Loader Script */
    data-map-container="mapContainer" /*This is the name of DOM element that holds  the  map  */
    data-params="maps,directions,places"
    data-callback="afterHereMapLoad" /*This  is the name  of the callback  method */
    data-libs="directions-renderer"
    data-parent="demos/directions-rendering-component/">
  </script>
  <link rel="icon" href="http://here.com/favicon.ico">
  <!--<link href="http://developer.here.com/html/css/main.css" rel="stylesheet" />-->
  <link href="css/routing.css" rel="stylesheet"/>
</head>
<body class="small-map">
  <h1>Showing  Directions Based on  a URL</h1>
  <p style="width:540px;"  >This example combines geocoding , routing and directions render to
    display  the  routing  instructions based on an input URL.
  </p>


  <div id="ticker" style="height:  2.0em; font-size: 2em; color: blue;"></div>
  <div id="mapContainer" style="width:540px; height:334px;float:left;" class="no-expand"></div>
  <div id="directions" style="float:left; color: rgb(102, 102, 102);height:334px;overflow:auto;"></div>
  <div id="uiContainer" style="clear:both;width:100%">
      Click on a link  to pre-open  the  directions renderer:<br>

      <ul>
        <li>
          <a href="query-string.html?addr1=Avenida  Dona Ana Costa Santos Brazil&amp;addr2=Avenida Paulista  S%C3%A3o Paulo Brazil">Street Level Routing</a>
          - Avenida Dona  Ana  Costa, Santos to Avenida Paulista, S&atilde;o Paulo
        </li>
        <li>
          <a href="query-string.html?addr1=Sacramento California&amp;addr2=San  Francisco California">City and State Routing.</a>
          - Sacramento, CA to  San  Francisco, CA
        </li>
        <li>
          <a href="query-string.html?addr1=Madrid,Spain&amp;addr2=Marsella,France&amp;ml=es">City to City Routing</a>
          - Madrid to Marseilles
        </li>
        <li>
          <a href="query-string.html?addr1=%E5%8C%97%E4%BA%AC&amp;addr2=%E4%B8%8A%E6%B5%B7">City to City Routing.</a>
          - &#21271;&#20140; (Beijing) to &#19978;&#28023; (Shanghai)
        </li>
        <li>
          <a href="query-string.html?addr1=Scotland Yard,London,UK&amp;addr2=221b  Baker Street,London,UK&amp;addr3=Bow+Street,WC2,London,UK&amp;sb=m">Routing with intermediate waypoints</a>
          - Scotland Yard  to Bow Street via 221b Baker Street  (distances in miles)
        </li>
        <li>
          <a href="query-string.html?lat1=-33.859972&amp;long1=151.212111&amp;lat2=-33.859972&amp;long2=151.211111&amp;lat3=-33.859972&amp;long3=151.19">Routing via geocoordinates</a>
          - around Sydney harbour.
        </li>
      </ul>
    </div>

  <div id="src" style="clear:both;width:100%" ><br/>
      <p>The control can be loaded using the following <code>&lt;script&gt;</code> element:
      <pre><code class='prettyprint'>&lt;script type="text/javascript" charset="UTF-8" src="<a href="libs/directions-renderer.js">libs/directions-renderer.js</a>"&gt;&lt;/script></code></pre>
    <p>Code:</p>
  </div>
<script id="example-code" data-categories="routing,library" type="text/javascript"  >
//<![CDATA[
var map,
  directionsRenderer,
  router,
  addressContainer,
  addresses,
  managersCount,
  managersFinished,
  geoCodedWaypoints,
  expectedWaypoints,
  infoBubbles;

function addDirectionsRenderer(map) {
  directionsRenderer = new DirectionsRenderer(document.getElementById('directions'));
  map.addComponent(directionsRenderer);
}

function onRouteCalculated(observedRouter,  key, value) {
  if (value === 'finished') {
    $('#ticker').text('');
    var  routes = observedRouter.getRoutes(),
    //create the default map representation  of a route
      mapRoute =
        new nokia.maps.routing.component.RouteResultSet(
          routes[0]
        ).container; //first option found
    map.objects.add(mapRoute);
    directionsRenderer.set('route', routes[0]);

    //Zoom to the bounding box of the route
    map.zoomTo(mapRoute.getBoundingBox(), false, 'default');
  } else if (value  === 'failed') {
    alert('The routing request failed.');
  }
}

function makeRouteRequest(geoCodedWaypoints) {
  var geoCodeSucceeded = true, // Assume  success...
    waypoints = new nokia.maps.routing.WaypointParameterList(),
    len =  geoCodedWaypoints.length,
    modes = [{
      type: 'shortest',
      transportModes:  ['car'],
      options: 'avoidTollroad',
      trafficMode: 'default'
    }],
    i;
  for (i = 0; i < len; i += 1) {
      // Check than none of the waypoints  are  null.
    if (geoCodedWaypoints[i]) {
      // It exists - add the waypoint  to the list  of places for the route.
      waypoints.addCoordinate(geoCodedWaypoints[i]);
    } else {
      // This  would mean we have failed to geocode an  address.
      geoCodeSucceeded = false;
      break;
    }
  }

  if (geoCodeSucceeded) {
    $('#ticker').text('Making Route Request');
    router = new nokia.maps.routing.Manager();
    router.addObserver('state',  onRouteCalculated);
    router.calculateRoute(waypoints, modes);
  } else {
    // We are missing at least one waypoint -  try  and  dislay what  we have  on screen.
    $('#ticker').text('Geocode Failed - insufficient waypoints');
    display.objects.add(addressContainer);
  }
}

// Geocoding Manager function -
// we will use the same  state observer function for all  managers.
// This  allows use to make concurrent requests.
//  Once all addresses have  been geocoded. We can start  the  route calculation.
function searchManager($index) {
  var that = this;
  that.$index  = $index;
  that.onSearchComplete =  function (data,  requestStatus) {
    // If the search has finished we can process the results
    if (requestStatus === 'OK') {
      geoCodedWaypoints[$index] = data.location.position;
      addressContainer.objects.add(
        new nokia.maps.map.StandardMarker(
          geoCodedWaypoints[$index],
          {text: ($index + 1)}
        )
      );
      //increment the counter to notify another  manager has finished
      managersFinished++;
    } else if (requestStatus === 'ERROR') {
      // we'll also increment in case of an error
      managersFinished++;
    }


    // if all managers are finished, we  call the final function
    if (managersFinished === managersCount) {
      // hence we get the bounding box of  the  container
      var bbox = addressContainer.getBoundingBox();
      // if the bounding box is null then  there are no objects inside
      // meaning no markers have been  added to it
      if (bbox) {
        // we have at least one address mapped so we zoomTo it
        map.zoomTo(bbox);
      }
      makeRouteRequest(geoCodedWaypoints);
    }
  }
}



function getParameterByName(name) {
  name = name.replace(/[\[]/,  '\\\[').replace(/[\]]/, '\\\]');
  var regex = new RegExp('[\\?&]'  + name + '=([^&#]*)'),
  results = regex.exec(location.search);
  return results === null ? '' :
    decodeURIComponent(results[1].replace(/\+/g, ' '));
}

function findWaypoints() {
  var i,
    lat,
    lng,
    addr;

  expectedWaypoints = 0;

  // Assume distances  will be  metric.  i.e. scale bar in kilometers.
  map.getComponentById('ScaleBar').set('showImperialUnits',
    'm' === getParameterByName('sb'), true);
  directionsRenderer.set('showImperialUnits',
    'm' === getParameterByName('sb'), true);

  addresses = [];
  managersFinished = 0;
  geoCodedWaypoints = [];
  addressContainer = new nokia.maps.map.Container();

  // Loop through  the  first 10 parameters  and  see  if the are addresses or  geo-coordinates.
  // Add them  to the appropriate bucket.
  for (i = 0; i < 10; i += 1) {
    lat = getParameterByName('lat' + i);
    lng = getParameterByName('long'  + i);
    addr = getParameterByName('addr' + i);
    if (addr != '') {
      addresses.push(getParameterByName('addr' + i));
      expectedWaypoints++;
    } else if (lat !== '' &&  lng  !== '') {
      geoCodedWaypoints.push(new nokia.maps.geo.Coordinate(
        parseFloat(lat),
        parseFloat(lng)
      ));
      expectedWaypoints++;
    }
  }


  // Concurrent search Manager set up.
  managersFinished = 0;

  // Assume we have at least one address to geocode.
  if (addresses.length >  1) {
    // iterate over  all  addresses, create a  manager for each of  them,
    // add the observer  and  call the geocode method.
    // Once  all  managers have completed
    // the calculateRouteFromKnownWaypoints() function will  be run.
    $('#ticker').text('Geo-coding Addresses');
    managersCount = addresses.length;
    var i = addresses.length;
    while (i--) {
      nokia.places.search.manager.geoCode({
        searchTerm: addresses[i],
          onComplete: new searchManager(i).onSearchComplete
      });
    }
  } else if (geoCodedWaypoints.length  > 1) {
    var i = geoCodedWaypoints.length;
    while (i--) {
      addressContainer.objects.add(
        new nokia.maps.map.StandardMarker(
          geoCodedWaypoints[i]
        )
      );
    }
    map.zoomTo(addressContainer.getBoundingBox());

    makeRouteRequest(geoCodedWaypoints);
  } else {
      // If we have neither addresses nor geolocations, we can't define a route.
      $('#ticker').text('No addresses found.');
  }
}



function afterHereMapLoad(theMap) {
  map = theMap;
  map.set('zoomLevel', 6);
  map.set('center', [43.674, 10.999]);

  infoBubbles  = new nokia.maps.map.component.InfoBubbles();
  infoBubbles.options.defaultWidth = 200;
  infoBubbles.options.width =  200;
  map.addComponent(infoBubbles);
  map.addComponent(new nokia.maps.map.component.ScaleBar());
  addDirectionsRenderer(map);
  findWaypoints();
}
//]]>
</script>
</body>
</html>
